package com.bb.flow.parser.impl.parsejson.parsenode.nodeimp;

import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.bb.flow.api.exception.ParseException;
import com.bb.flow.config.AbstractConfigNode;
import com.bb.flow.config.ClassInfo;
import com.bb.flow.config.ConditionInfo;
import com.bb.flow.config.ToNode;
import com.bb.flow.config.node.JudgeConfigNode;

import static com.bb.flow.util.Tools.isEmptyOrNull;

/**
 * @author bigbeard
 * 解析判断类型节点
 */
public class ParseJudgeNode extends AbstractNodeImp {

    @Override
    public AbstractConfigNode parse(JSONObject jsonObject, String flowTemplateName, String parentNodeKey) throws ParseException {

        JudgeConfigNode judgeConfigNode = new JudgeConfigNode();

        boolean b = parseNodeBaseInfo.parseNodeBaseInfo(judgeConfigNode, jsonObject, flowTemplateName);
        if (!b) {
            String s = String.format("流程模版[%s]节点,在解析基础字段时发生错误", flowTemplateName);
            throw new ParseException(s);
        }

        String nodeKey = getNodeKey(parentNodeKey, judgeConfigNode);

        JSONObject conditionJson = jsonObject.getJSONObject("Condition");

        if (null == parseCondition) {
            String s = String.format("流程模版[%s]节点,条件解析节点[%s]必须配置[Condition]属性,否则无法解析条件",
                    flowTemplateName, nodeKey);
            throw new ParseException(s);
        }
        ConditionInfo conditionInfo = parseCondition.parseCondition(conditionJson, nodeKey, flowTemplateName);
        if (null != conditionInfo) {
            judgeConfigNode.setCondition(conditionInfo);
        } else {
            String s = String.format("流程模版[%s]节点,条件解析节点[%s]解析[Condition]发生错误",
                    flowTemplateName, nodeKey);
            throw new ParseException(s);
        }

        JSONObject classInfoJson = jsonObject.getJSONObject("ClassInfo");
        if (null == classInfoJson) {
            String s = String.format("流程模版[%s]中的节点[%s]未配置功能实现类", flowTemplateName, nodeKey);
            throw new ParseException(s);
        }

        ClassInfo classInfo = parseClassInfo.parseClassInfo(classInfoJson, nodeKey, flowTemplateName);
        if (null != classInfo) {
            judgeConfigNode.setClassInfo(classInfo);
        } else {
            String s = String.format("流程模版[%s]中的节点[%s]解析[ClassInfo]失败,请确保类配置正确", flowTemplateName, nodeKey);
            throw new ParseException(s);
        }

        JSONArray toNodesJson = jsonObject.getJSONArray("ToNodes");
        if (null == toNodesJson) {
            String s = String.format("流程模版[%s]中的节点[%s]未配置去向节点", flowTemplateName, nodeKey);
            throw new ParseException(s);
        }

        for (int i = 0; i < toNodesJson.size(); i++) {
            JSONObject jsonObjectToNode = toNodesJson.getJSONObject(i);
            String expression = jsonObjectToNode.getString("Expression");
            ToNode toNode = new ToNode();
            if (!isEmptyOrNull(expression)) {
                toNode.setExpression(expression);
            }
            try {
                Integer orderIndex = jsonObjectToNode.getInteger("OrderIndex");
                toNode.setOrderIndex(orderIndex);
            } catch (Exception ex) {
                logger.error("流程模版[{}]中的节点[{}]中的去向节点[ToNodes]中的顺序[OrderIndex]属性配置错误",
                        flowTemplateName, nodeKey);
                toNode.setOrderIndex(0);
            }
            String toNodeKey = jsonObjectToNode.getString("NodeKey");
            toNode.setNodeKey(toNodeKey);
            try {
                Boolean needCalcNext = jsonObjectToNode.getBoolean("NeedCalcNext");
                toNode.setNeedCalcNext(needCalcNext);
            } catch (Exception ex) {
                logger.error("流程模版[{}]中的节点[{}]中的去向节点[{}]中的是否计算下一节点[NeedCalcNext]属性配置错误",
                        flowTemplateName, nodeKey, nodeKey);
                toNode.setNeedCalcNext(false);
            }
            judgeConfigNode.add(toNode);
        }

        return judgeConfigNode;
    }

}